#ifndef __DSTH_EVENT_LOOP_H__
#define __DSTH_EVENT_LOOP_H__

#include <vector>
#include "AcfDelegate.h"
#include "DSTHType.h"
#include "DSTHMutex.h"
#include "TimerId.h"
using namespace Acf;

namespace dsth {
class Channel;
class Connection;
class IMultiplex;
class Wakeup;
class TimerQueue;
class Timestamp;
class DSTHIocp;
class EventLoop {
public:
    typedef Delegate<void ()> EventTask;
    typedef std::vector<Channel*> ChannelList;
    typedef std::vector<Connection*> ErasedConnectionList;
    EventLoop();
    ~EventLoop();
    void Loop();
    void Quit();
    void RunInLoop(const EventTask& task);
    bool IsInLoopThread();

    // Timer functions
    TimerId RunAt(const Timestamp& when, const TimerCallBack& cb);
    TimerId RunAfterMilliSeconds(uint64_t duetime, const TimerCallBack& cb);
    TimerId RunPeriodMilliSeconds(uint64_t period, const TimerCallBack& cb);

private:
    // Can't invoke copy constructor or assignment operator
    EventLoop(const EventLoop&);
    void operator=(const EventLoop&);

    bool looping_;
    bool stop_;
#if defined(DSTH_IOCP)
    void AsyncAccept(SOCKET accept_socket, LPOVERLAPPED op);
    void RegisterHandle(HANDLE handle);
    std::auto_ptr<DSTHIocp> proactor_;
#else
    void Update(Channel* channel);
    void Remove(Channel* channel);
    void RunAllTasks();
    void AddErasedConnection(Connection*);
    void SelfWaken();
    friend class Connection;
    friend class Channel;
    friend class Connector;
    bool polling_;
    pid_t thread_id_;
    std::auto_ptr<IMultiplex> multiplexor_;
    Mutex mutex_; // Guard tasks_;
    EventTask tasks_;
    std::auto_ptr<Wakeup> wakeup_;
    std::auto_ptr<TimerQueue> timer_queuer_;
    ChannelList channel_list_;
    ErasedConnectionList conn_list_;
#endif
};

} // namespace
#endif // __DSTH_EVENT_LOOP_H__
